package com.api.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class httpClient2 {
    private static PoolingHttpClientConnectionManager connectionManager;

    private static RequestConfig requestConfig;
    private final static CloseableHttpClient httpClient;

    static {
        connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(200);         // 全局最大连接数
        connectionManager.setDefaultMaxPerRoute(20); // 每个路由最大连接数

        requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(10000)
                .setConnectionRequestTimeout(6000)
                .build();

        httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .build();
    }

    public static String doPostFile(String host, String path,
                                    Map<String, String> headers,
                                    Map<String, String> querys,
                                    File file,
                                    Map<String, String> proxy)
            throws Exception {
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        // request.setConfig(requestConfig);
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> e : headers.entrySet()) {
                request.addHeader(e.getKey(), e.getValue());
            }
        }
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entityBuilder.setCharset(Consts.UTF_8);
        entityBuilder.addBinaryBody("file", Files.newInputStream(file.toPath()), ContentType.DEFAULT_BINARY, file.getName());
        System.out.println(file.getName());
        request.setEntity(entityBuilder.build());
        return executeToPost(request, Consts.UTF_8.name(), proxy);
    }

    public static String sendPost(String url, Map<String, String> headers, Map<String, String> messages, String responseEncoding, Map<String, String> proxy) {
        /*RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(5000)
                .setConnectionRequestTimeout(5000).build();*/

        try {
            HttpPost post = new HttpPost(url);
            if (headers != null && !headers.isEmpty()) {
                for (Map.Entry<String, String> e : headers.entrySet()) {
                    post.addHeader(e.getKey(), e.getValue());
                }
            }
            // post.setConfig(requestConfig);
            //post.addHeader("Content-Type", "application/json");
            if (!messages.isEmpty()) {
                // 创建参数列表
                List<NameValuePair> params = new ArrayList<>();
                for (Map.Entry<String, String> entry : messages.entrySet()) {
                    params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                post.setEntity(new UrlEncodedFormEntity(params));
            }
            return executeToPost(post, responseEncoding, proxy);
        } catch (IOException e) {
            throw new BaseException(e.getMessage());
        }
    }


    public static String sendPostJson(String url, Map<String, String> headers, String message, String responseEncoding, Map<String, String> proxy) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(5000)
                .setConnectionRequestTimeout(5000).build();
        try {
            HttpPost post = new HttpPost(url);
            // post.setHeaders(headers);
            if (headers != null && !headers.isEmpty()) {
                for (Map.Entry<String, String> e : headers.entrySet()) {
                    post.addHeader(e.getKey(), e.getValue());
                }
            }
            post.setConfig(requestConfig);
            //post.addHeader("Content-Type", "application/json");
            post.setEntity(new StringEntity(message, responseEncoding));
            return executeToPost(post, responseEncoding, proxy);
        } catch (IOException e) {
            log.info("请求异常", e);
            throw new BaseException(e.getMessage());
        }
    }

    /**
     * 发送xml格式数据
     * @param url
     * @param headers
     * @param message
     * @param responseEncoding
     * @param proxy
     * @return
     */
    public static String sendPostXml(String url, Map<String, String> headers, String message, String responseEncoding, Map<String, String> proxy) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(5000)
                .setConnectionRequestTimeout(5000).build();


        if (responseEncoding == null) {
            responseEncoding = "UTF-8";
        }

        try {
            HttpPost post = new HttpPost(url);
            // post.setHeaders(headers);
            if (headers != null && !headers.isEmpty()) {
                for (Map.Entry<String, String> e : headers.entrySet()) {
                    post.addHeader(e.getKey(), e.getValue());
                }
            }
            post.setConfig(requestConfig);
            //post.addHeader("Content-Type", "application/json");
            post.setEntity(new StringEntity(message, responseEncoding));
            return executeToPost(post, responseEncoding, proxy);
        } catch (IOException e) {
            log.info("请求异常", e);
            throw new BaseException(e.getMessage());
        }
    }


    public String sendGet(String url, Map<String, String> headers, Map<String, String> messages, String responseEncoding, HashMap<String, String> proxy) {
        // if (proxy !=null && !proxy.isEmpty() && "1".equals(proxy.get("openProxy"))){
        //     HttpHost proxyConfig = new HttpHost(proxy.get("proxyHost"), Integer.parseInt(proxy.get("proxyPort")));
        // }
        // RequestConfig httpConfig = RequestConfig.copy(requestConfig)
        //         .setConnectTimeout(5000)
        //         .setSocketTimeout(6000)
        //         .setConnectionRequestTimeout(5000)
        //         .setProxy(proxyConfig)
        //         .build();
        try {
            HttpGet get = null;
            //3、转化参数
            if (messages != null && !messages.isEmpty()) {
                List<NameValuePair> lists = new ArrayList<>();
                for (Map.Entry<String, String> entry : messages.entrySet()) {
                    lists.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }

                String params = EntityUtils.toString(new UrlEncodedFormEntity(lists, responseEncoding));
                get = new HttpGet(url + "?" + params);
            } else {
                get = new HttpGet(url);
            }
            if (headers != null && !headers.isEmpty()) {
                for (Map.Entry<String, String> e : headers.entrySet()) {
                    get.addHeader(e.getKey(), e.getValue());
                }
            }
            // get.setConfig(httpConfig);
            return executeToGet(get, responseEncoding, proxy);
        } catch (IOException e) {
            log.info("请求异常", e);
        }
        return null;
    }


    private String executeToGet(HttpGet httpGet, String responseEncoding, HashMap<String, String> proxy) throws IOException {
        if (responseEncoding == null) {
            responseEncoding = "UTF-8";
        }

        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            log.info("http status ---- {}", response.getStatusLine());
            String result = "null";
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), responseEncoding);
                log.info("返回结果:{}", result);
            } else {
                log.warn("返回异常:{}", EntityUtils.toString(response.getEntity()));
            }
            return result;
        }
    }


    private static String executeToPost(HttpPost httpPost, String responseEncoding, Map<String, String> proxy) throws IOException {
        if (responseEncoding == null) {
            responseEncoding = "UTF-8";
        }
        //初始HttpClient
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            response.getEntity();
            log.info("http status ---- {}", response.getStatusLine());
            String result = "null";
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), responseEncoding);
                log.info("返回结果:{}", result);
            } else {
                log.warn("返回异常:{}", EntityUtils.toString(response.getEntity()));
            }
            return result;
        }
    }


    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (!StringUtils.isBlank(path)) {
            sbUrl.append(path);
        }
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String, String> query : querys.entrySet()) {
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
                    sbQuery.append(query.getValue());
                }
                if (!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if (!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }

        }
        log.info("访问路径: {}", sbUrl);
        return sbUrl.toString();
    }


}